package idiolect.core;

import idiolect.helpers.Worker;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

public class Topic {
    String name;
    List<Word> words = new ArrayList<Word>();
    File file;
    private boolean sorted = false;

    public Topic(String name) {
        this.name = name;
        this.file = new File(IOUtil.FOLDER, name.endsWith(".dict") ? name : (name + ".dict"));
    }


    public Topic(Topic source) {
        this(source.name);
        this.file = source.file;
        words.addAll(source.words);
    }

    void setSortedMode(boolean sorted) {
        if (this.sorted == sorted)
            return;
        this.sorted = sorted;
        if (sorted)
            Collections.sort(words);
        else
            Collections.sort(words, Word.INDEX_COMPARATOR);
    }

    public int getMaxIndex() {
        int max = 0;
        for (Word word : words)
            max = Math.max(word.index, max);
        return max;
    }

    public boolean isSorted() {
        return sorted;
    }

    public static Future<Topic> load(final File f) {
        return Worker.getInstance().submit(new Callable<Topic>() {
            public Topic call() throws Exception {
                int pos = f.getName().lastIndexOf('.');
                boolean dat = f.getName().endsWith(".dat");
                Topic topic = new Topic(pos != -1 ? f.getName().substring(0, pos) : f.getName());
                topic.file = f;
                BufferedReader br = null;
                try {
                    br = new BufferedReader(new FileReader(f));
                    int index = 0;
                    int lines = 0;
                    for (String s = br.readLine(); s != null; s = br.readLine()) {
                        lines++;
                        s = s.trim();
                        if (s.startsWith("#") || s.length() == 0)//comment
                            continue;
                        if (s.length() > 512 || lines - index > 100) {
                            topic = null;
                            break;
                        }
                        Word w = Word.parseWord(s, index, !dat);
                        if (w != null) {
                            w.original = w.original.replace("(l)", "");
                            w.original = w.original.replace("(ll)", "");
                            w.original = w.original.replace("(I)", "");
                            w.original = w.original.replace("(II)", "");
                            int i = topic.words.indexOf(w);
                            if (i != -1) {
                                topic.words.get(i).translation += "; " + w.translation;
                            } else {
                                topic.words.add(w);
                            }
                            index++;
                        }
                    }
                } catch (IOException ioe) {
                    System.out.println(ioe);
                    return null;
                } finally {
                    IOUtil.close(br);
                }
                return topic;
            }
        });
    }


    void save() {
        Worker.getInstance().addTask(new Runnable() {
            public void run() {
                PrintWriter pw = null;
                try {
                    convertFileExtensionIfNeed();
                    pw = new PrintWriter(new FileWriter(file));
                    pw.println("#" + name);
                    List<Word> copy = new ArrayList<Word>(words);
                    Collections.sort(copy, Word.INDEX_COMPARATOR);
                    for (Word word : copy)
                        pw.println(word.toLine());
                    pw.flush();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                } finally {
                    IOUtil.close(pw);
                }
            }
        });
    }

    private void convertFileExtensionIfNeed() {
        if (!file.getName().endsWith(".dict")) {
            int pos = file.getName().lastIndexOf('.');
            if (pos == -1)
                pos = file.getName().length();
            file = new File(file.getParentFile(), file.getName().substring(0, pos) + ".dict");
        }
    }
}
